home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / misc / sci / RARS_Amiga_3.lha / RARS / os.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-27  |  9.4 KB  |  456 lines

  1. /*
  2.  * $RCSfile: os.cpp $
  3.  *
  4.  * $Author: marcel $
  5.  *
  6.  * $Revision: 1.8 $
  7.  *
  8.  * $Date: 1995/05/15 11:28:02 $
  9.  *
  10.  * $Locker: marcel $
  11.  *
  12.  * $State: Exp $
  13.  *
  14.  * Amiga version
  15.  *
  16.  * Copyright © 1995 Marcel Offermans
  17.  *
  18.  * tabsize = 5
  19.  */
  20.  
  21. /* includes */
  22. #include <exec/memory.h>
  23. #include <intuition/intuition.h>
  24. #include <proto/exec.h>
  25. #include <proto/dos.h>
  26. #include <proto/intuition.h>
  27. #include <dos.h>
  28. #include <time.h>
  29. #include <ctype.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include "track.h"
  33. #include "os.h"
  34. #include "car.h"
  35.  
  36. #define TEMPLATE                "TRACK,DRIVERS/M,CARS/N,PRACTICELAPS/N,LAPS/N,RACES/N,SURFACETYPE/N,KEEPORDER/S,NOREALTIME/S,NODISPLAY/S,NORANDOMSEED/N,NORANDOM/S,NOKEYBOARD/S,HELP/S,NOGUI/S,SCREENDEPTH/N,SCREENWIDTH/N,SCREENHEIGHT/N,SCREENMODEID/N,SCREENOVERSCANTYPE/N,SCREENNOAUTOSCROLL/S"
  37. #define OPT_TRACK                0
  38. #define OPT_DRIVERS                1
  39. #define OPT_CARS                2
  40. #define OPT_PRACTICELAPS            3
  41. #define OPT_LAPS                 4
  42. #define OPT_RACES                5
  43. #define OPT_SURFACETYPE            6
  44. #define OPT_KEEPORDER            7
  45. #define OPT_NOREALTIME           8
  46. #define OPT_NODISPLAY            9
  47. #define OPT_NORANDOMSEED         10
  48. #define OPT_NORANDOM             11
  49. #define OPT_NOKEYBOARD            12
  50. #define OPT_HELP                13
  51. #define OPT_NOGUI                14
  52. #define OPT_SCREENDEPTH            15
  53. #define OPT_SCREENWIDTH            16
  54. #define OPT_SCREENHEIGHT            17
  55. #define OPT_SCREENMODEID            18
  56. #define OPT_SCREENOVERSCANTYPE    19
  57. #define OPT_SCREENNOAUTOSCROLL    20
  58. #define OPT_COUNT                21
  59.  
  60. #define ENVBUFSIZE 1024
  61.  
  62. /* externals */
  63. extern "C" VOID show_gui(VOID);
  64. extern car_ID drivers[];
  65. void print_help_file(void);
  66. int find_name(char *);
  67. void version_report(void);
  68. void Randomize(long);
  69.  
  70. /* globals */
  71. static char                version_ptr[]        = "\0$VER: RARS_Amiga 3.0 " __AMIGADATE__ ;
  72. int                        rndmiz            = 1;
  73. int                        no_waiting        = 0;
  74. int                        randomotion        = 1;
  75. int                        practice            = 0;
  76. static long                seed                = 0L;
  77. struct RDArgs *            args_ptr            = NULL;
  78. struct IntuiMessage *        imsg_ptr            = NULL;
  79. struct IntuiMessage            imsg;
  80. LONG                        opts[OPT_COUNT];
  81. ULONG                    idcmpmask;
  82. ULONG                    signals;
  83. struct RDArgs *            rdargs_ptr        = NULL;
  84. UBYTE                    envbuf_ptr[ENVBUFSIZE];
  85.  
  86. /* filenames are case insensitive on the Amiga and therefore we need this string comparison routine */
  87. int strcmpnocase(char *s_ptr, char *t_ptr)
  88. {
  89.     int i;
  90.  
  91.     for (i = 0; toupper(s_ptr[i]) == toupper(t_ptr[i]); i++)
  92.     {
  93.         if (s_ptr[i] == '\0')
  94.         {
  95.             return(0);
  96.         }
  97.     }
  98.     return(toupper(s_ptr[i]) - toupper(t_ptr[i]));
  99. }
  100.  
  101. /* initialize the random number generator based on the current time */
  102. void randomizer(void)
  103. {
  104.     if (rndmiz)
  105.     {
  106.         Randomize(0);
  107.     }
  108.     else if (seed)
  109.     {
  110.         Randomize(seed);
  111.     }
  112.     return;
  113. }
  114.  
  115. /* return a random number between 0 and limit */
  116. double random(int limit)
  117. {
  118.     return(((double)rand() / (double)RAND_MAX) * (double)limit);
  119. }
  120.  
  121. /* convert integer to ascii */
  122. void itoa(int value, char *buffer_ptr, int base)
  123. {
  124.     if (base == 10)
  125.     {
  126.         stci_d(buffer_ptr, value);
  127.     }
  128. }
  129.  
  130. /* get arguments by using a standard command line template */
  131. void get_args(int argc, char* argv[])
  132. {
  133.     int i, n, loop;
  134.     car_ID temp_drv;
  135.     char **driver_ptr_ptr;
  136.     BOOL nogui = FALSE;
  137.  
  138.     /* set up defaults */
  139.     strcpy(trackfile, "Trackfile.trk");
  140.     lap_count = 4;
  141.     car_count = 6;
  142.     real_speed = 1;
  143.     race_count = 2;
  144.     keep_order = 0;
  145.     surface = 0;
  146.  
  147.     /* get environment variables */
  148.     if (GetVar("RARSOPTS", (STRPTR)envbuf_ptr, (long)ENVBUFSIZE, (long)0) > 0)
  149.     {
  150.         strcat((char *)envbuf_ptr, "\n");
  151.         if (rdargs_ptr = (struct RDArgs *)AllocDosObjectTagList(DOS_RDARGS, NULL))
  152.         {
  153.             rdargs_ptr->RDA_Source.CS_Buffer = envbuf_ptr;
  154.             rdargs_ptr->RDA_Source.CS_Length = ENVBUFSIZE;
  155.             rdargs_ptr->RDA_Source.CS_CurChr = 0;
  156.             rdargs_ptr->RDA_Buffer = NULL;
  157.             rdargs_ptr->RDA_Flags = RDAF_NOPROMPT;
  158.         }
  159.     }
  160.  
  161.     /* get arguments */
  162.     for (loop = 0; loop < 2; loop++)
  163.     {
  164.         if (loop == 0)
  165.         {
  166.             if (rdargs_ptr == NULL)
  167.             {
  168.                 continue;
  169.             }
  170.         }
  171.  
  172.         memset(opts, 0, OPT_COUNT * sizeof(LONG));
  173.  
  174.         if (args_ptr = ReadArgs(TEMPLATE, opts, (loop == 0) ? (rdargs_ptr) : (NULL)))
  175.         {
  176.             if (opts[OPT_TRACK])
  177.             {
  178.                 /* track file name */
  179.                 strcpy(trackfile, (char *)opts[OPT_TRACK]);
  180.             }
  181.             if (opts[OPT_DRIVERS])
  182.             {
  183.                 /* list of drivers in the race */
  184.                 driver_ptr_ptr = (char **)opts[OPT_DRIVERS];
  185.                 for (n = 0; n < MAXCARS; n++)
  186.                 {
  187.                     if (driver_ptr_ptr[n] == NULL)
  188.                     {
  189.                         break;
  190.                     }
  191.                     if ((i = find_name(driver_ptr_ptr[n])) < 0)
  192.                     {
  193.                         break;
  194.                     }
  195.                     temp_drv = drivers[n];
  196.                     drivers[n] = drivers[i];
  197.                     drivers[i] = temp_drv;
  198.                 }
  199.                 /* if any drivers were found, set the number of cars to the number of drivers */
  200.                 if (n > 0)
  201.                 {
  202.                     car_count = n;
  203.                 }
  204.             }
  205.             if (opts[OPT_LAPS])
  206.             {
  207.                 /* number of laps to go */
  208.                 lap_count = (int)(*((LONG *)opts[OPT_LAPS]));
  209.     
  210.                 /* check bounds of user input */
  211.                 if (lap_count <= 0)
  212.                 {
  213.                     lap_count = 1;
  214.                 }
  215.             }
  216.             if (opts[OPT_PRACTICELAPS])
  217.             {
  218.                 /* number of laps to go */
  219.                 practice = (int)(*((LONG *)opts[OPT_PRACTICELAPS]));
  220.     
  221.                 /* check bounds of user input */
  222.                 if (practice < 0)
  223.                 {
  224.                     practice = 0;
  225.                 }
  226.             }
  227.             if (opts[OPT_SURFACETYPE])
  228.             {
  229.                 /* number of laps to go */
  230.                 surface = (int)(*((LONG *)opts[OPT_SURFACETYPE]));
  231.     
  232.                 /* check bounds of user input */
  233.                 if (surface < 0)
  234.                 {
  235.                     surface = 0;
  236.                 }
  237.             }
  238.             if (opts[OPT_CARS])
  239.             {
  240.                 /* number of cars in the race */
  241.                 car_count = (int)(*((LONG *)opts[OPT_CARS]));
  242.     
  243.                 /* check bounds of user input */
  244.                 if (car_count < 0)
  245.                 {
  246.                     /* zero cars is legal, and only shows you the track */
  247.                     car_count = 0;
  248.                 }
  249.                 else if (car_count > MAXCARS)
  250.                 {
  251.                     car_count = MAXCARS;
  252.                 }
  253.             }
  254.             if (opts[OPT_RACES])
  255.             {
  256.                 /* number of races to go */
  257.                 race_count = (int)(*((LONG *)opts[OPT_RACES]));
  258.     
  259.                 /* check bounds of user input */
  260.                 if (race_count <= 0)
  261.                 {
  262.                     race_count = 1;
  263.                 }
  264.             }
  265.             if (opts[OPT_NOREALTIME])
  266.             {
  267.                 /* run as fast as possible instead of real-time */
  268.                 real_speed = 0;
  269.             }
  270.             if (opts[OPT_NORANDOMSEED])
  271.             {
  272.                 /* don't set a new random seed every time */
  273.                 rndmiz = 0;
  274.     
  275.                 /* set the seed */
  276.                 seed = (int)(*((LONG *)opts[OPT_NORANDOMSEED]));
  277.             }
  278.             if (opts[OPT_NODISPLAY])
  279.             {
  280.                 /* don't use a graphics display */
  281.                 no_display = 1;
  282.             }
  283.             if (opts[OPT_KEEPORDER])
  284.             {
  285.                 /* keep the starting order */
  286.                 keep_order = 1;
  287.             }
  288.             if (opts[OPT_NORANDOM])
  289.             {
  290.                 /* don't randomize at all */
  291.                 rndmiz = 0;
  292.                 randomotion = 0;
  293.             }
  294.             if (opts[OPT_NOKEYBOARD])
  295.             {
  296.                 /* don't process user keystrokes */
  297.                 no_waiting = 1;
  298.             }
  299.             if (opts[OPT_HELP])
  300.             {
  301.                 /* show help and quit */
  302.                 print_help_file();
  303.                 FreeArgs(args_ptr);
  304.                 exit(0);
  305.             }
  306.             if (opts[OPT_NOGUI])
  307.             {
  308.                 /* don't display the GUI */
  309.                 nogui = TRUE;
  310.             }
  311.             if (opts[OPT_SCREENDEPTH])
  312.             {
  313.                 scrdepth = (ULONG)(*((LONG *)opts[OPT_SCREENDEPTH]));
  314.             }
  315.             if (opts[OPT_SCREENWIDTH])
  316.             {
  317.                 scrwidth = (ULONG)(*((LONG *)opts[OPT_SCREENWIDTH]));
  318.             }
  319.             if (opts[OPT_SCREENHEIGHT])
  320.             {
  321.                 scrheight = (ULONG)(*((LONG *)opts[OPT_SCREENHEIGHT]));
  322.             }
  323.             if (opts[OPT_SCREENMODEID])
  324.             {
  325.                 scrid = (ULONG)(*((LONG *)opts[OPT_SCREENMODEID]));
  326.             }
  327.             if (opts[OPT_SCREENOVERSCANTYPE])
  328.             {
  329.                 scroscantype = (ULONG)(*((LONG *)opts[OPT_SCREENOVERSCANTYPE]));
  330.             }
  331.             if (opts[OPT_SCREENNOAUTOSCROLL])
  332.             {
  333.                 scrautoscroll = FALSE;
  334.             }
  335.             FreeArgs(args_ptr);
  336.         }
  337.     }
  338.  
  339.     if (rdargs_ptr)
  340.     {
  341.         FreeDosObject(DOS_RDARGS, (void *)rdargs_ptr);
  342.         rdargs_ptr = NULL;
  343.     }
  344.  
  345.     /* show the GUI unless the user turned it off */
  346.     if (nogui == FALSE)
  347.     {
  348.         show_gui();
  349.     }
  350. }
  351.  
  352. /* blocks until one character is read from the keyboard */
  353. int get_ch(void)
  354. {
  355.     if (!available)
  356.     {
  357.         /* if there's no graphics display, we don't handle the keyboard */
  358.         return(0);
  359.     }
  360.  
  361.     /* wait for a message if we don't have a cached message yet */
  362.     while (imsg_ptr == NULL)
  363.     {
  364.         /* if we don't want to wait for a key, then fall through */
  365.         if (!(no_waiting))
  366.         {
  367.             signals = Wait(idcmpmask);
  368.         }
  369.         else
  370.         {
  371.             signals = idcmpmask;
  372.         }
  373.         if (signals & idcmpmask)
  374.         {
  375.             imsg_ptr = (struct IntuiMessage *)GetMsg(window_ptr->UserPort);
  376.             if (imsg_ptr)
  377.             {
  378.                 CopyMem((char *)imsg_ptr, (char *)&imsg, (long)sizeof(struct IntuiMessage));
  379.                 ReplyMsg((struct Message *)imsg_ptr);
  380.             }
  381.             else if (no_waiting)
  382.             {
  383.                 /* return a code if we don't want to wait */
  384.                 imsg.Code = ' ';
  385.             }
  386.         }
  387.     }
  388.  
  389.     /* reset the pointer because at this point the message is processed */
  390.     imsg_ptr = NULL;
  391.  
  392.     /* return the key code */
  393.     return(imsg.Code);
  394. }
  395.  
  396. /* this routine returns non-zero if there's input available for get_ch() and 0 if not */
  397. int kb_hit(void)
  398. {
  399.     if (!available)
  400.     {
  401.         /* if there's no graphics display, we don't handle the keyboard */
  402.         return(0);
  403.     }
  404.  
  405.     imsg_ptr = (struct IntuiMessage *)GetMsg(window_ptr->UserPort);
  406.     if (imsg_ptr)
  407.     {
  408.         /* we received a message, so now we have to cache it until get_ch() is called */
  409.         CopyMem((char *)imsg_ptr, (char *)&imsg, (long)sizeof(struct IntuiMessage));
  410.         ReplyMsg((struct Message *)imsg_ptr);
  411.         return(1);
  412.     }
  413.     else
  414.     {
  415.         return(0);
  416.     }
  417. }
  418.  
  419. /* busy wait for a tick to go by */
  420. void one_tick(int initialize = 0)
  421. {
  422.     static unsigned int pre_clock[2];
  423.     static unsigned int cur_clock[2];
  424.  
  425.     if (initialize)
  426.     {
  427.         timer(pre_clock);
  428.     }
  429.     else
  430.     {
  431.         do
  432.         {
  433.             timer(cur_clock);
  434.         }
  435.         while (cur_clock[1] + 1000000 * (cur_clock[0] - pre_clock[0]) < pre_clock[1] + (int)(delta_time * 1000000));
  436.  
  437.         pre_clock[0] = cur_clock[0];
  438.         pre_clock[1] = cur_clock[1];
  439.     }
  440. }
  441.  
  442. /* return the amount of free RAM in K */
  443. int RAM_query(void)
  444. {
  445.     return(AvailMem(MEMF_ANY) >> 10);
  446. }
  447.  
  448. /* return a random number based on the clock */
  449. long pick_random(void)  
  450. {
  451.     unsigned int clock[2];
  452.  
  453.     timer(clock);
  454.     return((long)clock[1]);
  455. }
  456.